﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace CPPEI.ETL.Domain.Services
{
    public class DVPlugInService
    {
        public ServiceResult<Models.MDVPlugInAssembly> Parse(byte[] data)
        {
            Models.MDVPlugInAssembly dvAssembly = null;

            try
            {
                Assembly assembly = Assembly.Load(data);

                Type[] types = assembly.GetTypes();
                foreach (var type in types)
                {
                    if(typeof(CPPEI.ETL.Domain.DataVerification.IDataVerification).IsAssignableFrom(type))
                    {
                        if(dvAssembly == null)
                        {
                            dvAssembly = new Models.MDVPlugInAssembly();
                            dvAssembly.Id = Guid.NewGuid();
                            dvAssembly.Assembly = assembly.FullName;
                            dvAssembly.Version = assembly.GetName().Version.ToString(4);
                        }
                        // 数据审核插件类
                        Models.MDVPlugIn plugin = new Models.MDVPlugIn();
                        plugin.Name = type.FullName;
                        plugin.Id = Guid.NewGuid();
                        plugin.Description = string.Empty;

                        dvAssembly.Items.Add(plugin);
                    }
                }

                if(dvAssembly == null)
                {
                    return new ServiceResult<Models.MDVPlugInAssembly>(false, ErrorCode.DVPlugIn_NoPlugIn, ErrorCode.String(ErrorCode.DVPlugIn_NoPlugIn));
                }
                else
                {
                    return new ServiceResult<Models.MDVPlugInAssembly>(true, ErrorCode.COM_NoError, ErrorCode.String(ErrorCode.COM_NoError), dvAssembly);

                }
            }
            catch(Exception ex)
            {
                Logger.ErrorToTag(Library.LogTAG, string.Format("加载程序集出错!", ex));

                return new ServiceResult<Models.MDVPlugInAssembly>(true, ErrorCode.COM_NoError, ErrorCode.String(ErrorCode.COM_NoError));
            }
        }

        public ServiceResult Publish(Guid assebmlyId, string assemblyName, string assemblyVersion, string plugInSettings)
        {
            if(string.IsNullOrEmpty(plugInSettings))
            {
                return new ServiceResult(false, ErrorCode.COM_InvalidParameter, ErrorCode.String(ErrorCode.COM_InvalidParameter));
            }

            // id,name,description,id,name,description
            string[] plugInArr = plugInSettings.Split(new char[] { ',' });
            if(plugInArr.Length / 3 == 0
                || plugInArr.Length % 3 != 0)
            {
                return new ServiceResult(false, ErrorCode.DVPlugIn_InvalidPlugInSettings, ErrorCode.String(ErrorCode.DVPlugIn_InvalidPlugInSettings));
            }

            using (EtlDbContext dbContext = new EtlDbContext())
            {
                EntityRepository<Entities.EDVPlugInAssembly> dvpiaRep = new EntityRepository<Entities.EDVPlugInAssembly>(dbContext);
                EntityRepository<Entities.EDVPlugIn> dvpiRep = new EntityRepository<Entities.EDVPlugIn>(dbContext);

                Entities.EDVPlugInAssembly eDvPluginAssembly = new Entities.EDVPlugInAssembly();
                eDvPluginAssembly.Id = assebmlyId;
                eDvPluginAssembly.Assembly = assemblyName;
                eDvPluginAssembly.Version = assemblyVersion;

                dvpiaRep.Create(eDvPluginAssembly);

                for (int index = 0; index < plugInArr.Length; index += 3)
                {
                    Entities.EDVPlugIn ePlugin = new Entities.EDVPlugIn();
                    ePlugin.AssemblyId = assebmlyId;
                    ePlugin.Id = new Guid(plugInArr[index]);
                    ePlugin.Name = plugInArr[index + 1];
                    ePlugin.Description = plugInArr[index + 2];

                    dvpiRep.Create(ePlugin);
                }

                try
                {
                    if (dbContext.SaveChanges() > 0)
                    {
                        return new ServiceResult(true, ErrorCode.COM_NoError, ErrorCode.String(ErrorCode.COM_NoError));
                    }
                    else
                    {
                        return new ServiceResult(false, ErrorCode.COM_DBError, ErrorCode.String(ErrorCode.COM_DBError));
                    }
                }
                catch (Exception ex)
                {
                    Logger.ErrorToTag(Library.LogTAG, string.Format("发布数据审核插件:{0},出错,ex:{1}!", assemblyName, ex));

                    return new ServiceResult(false, ErrorCode.COM_NoError, ErrorCode.String(ErrorCode.COM_NoError));
                }
            }
        }

        public PagedList<Entities.EDVPlugInAssembly> GetAssemblyList(string filter, int start, int limit)
        {
            using (EtlDbContext dbContext = new EtlDbContext())
            {
                EntityRepository<Entities.EDVPlugInAssembly> dvpiaRep = new EntityRepository<Entities.EDVPlugInAssembly>(dbContext);

                if (string.IsNullOrEmpty(filter))
                {
                    List<Entities.EDVPlugInAssembly> list = dvpiaRep.Query().Take(limit).Skip(start).ToList();
                    int total = dvpiaRep.Count();

                    return new PagedList<Entities.EDVPlugInAssembly>(true, ErrorCode.COM_NoError, ErrorCode.String(ErrorCode.COM_NoError), start, limit,
                        total,
                        list);
                }
                else
                {
                    List<Entities.EDVPlugInAssembly> list = dvpiaRep.Query(p=>p.Assembly.Contains(filter)).Take(limit).Skip(start).ToList();
                    int total = dvpiaRep.Count(p => p.Assembly.Contains(filter));

                    return new PagedList<Entities.EDVPlugInAssembly>(true, ErrorCode.COM_NoError, ErrorCode.String(ErrorCode.COM_NoError), start, limit,
                        total,
                        list);
                }
            }
        }

        public PagedList<Entities.EDVPlugIn> GetPlugInList(Guid assemblyId, int start, int limit)
        {
            if(assemblyId == Guid.Empty)
            {
                return new PagedList<Entities.EDVPlugIn>(false, ErrorCode.COM_InvalidParameter, ErrorCode.String(ErrorCode.COM_InvalidParameter));
            }

            using (EtlDbContext dbContext = new EtlDbContext())
            {
                EntityRepository<Entities.EDVPlugIn> dvpiRep = new EntityRepository<Entities.EDVPlugIn>(dbContext);

                List<Entities.EDVPlugIn> list = dvpiRep.Query(p => p.AssemblyId == assemblyId).Take(limit).Skip(start).ToList();
                int total = dvpiRep.Count();

                return new PagedList<Entities.EDVPlugIn>(true, ErrorCode.COM_NoError, ErrorCode.String(ErrorCode.COM_NoError), start, limit, total, list);
            }
        }

        public ServiceResult<Views.VDVPlugIn> GetPlugIn(Guid id)
        {
            using (EtlDbContext dbContext = new EtlDbContext())
            {
                EntityRepository<Views.VDVPlugIn> dpiRep = new EntityRepository<Views.VDVPlugIn>(dbContext);
                Views.VDVPlugIn plugIn = dpiRep.Get(p => p.Id == id);
                return new ServiceResult<Views.VDVPlugIn>(true, ErrorCode.COM_NoError, ErrorCode.String(ErrorCode.COM_NoError), plugIn);
            }
        }
    }
}
